import java.io.IOException;

import javax.swing.JOptionPane;

/**
 * Copyright (C) 2013  Arun Lee & Bryce Nagareda
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * Creates a GUI for the sundial.
 * @author briceorbryce
 */
public class SunDialgui extends javax.swing.JFrame {

	/**Serial UID*/private static final long serialVersionUID = 1L;

	/**Saves the coordinates from the last successful run.*/
	private SundialSave saveCoordinates = new SundialSave();
	
	private java.net.URI uri;
	
	
	/**
	 * Creates new form SunDialgui
	 */
	public SunDialgui() {
		initComponents();
		// starts the JFrame in the middle of the screen
		this.setLocationRelativeTo(null);

		createURI();
	}

	/**
	 * This method is called from within the constructor to initialize the form.
	 * WARNING: Do NOT modify this code. The content of this method is always
	 * regenerated by the Form Editor.
	 */
	private void initComponents() {
		this.buttonGroupDiffSundials = new javax.swing.ButtonGroup();
		this.jLabelLatitude = new javax.swing.JLabel();
		this.jTextFieldLatitude = new javax.swing.JTextField();
		this.jTextFieldLongitude = new javax.swing.JTextField();
		this.jLabelLongtitude = new javax.swing.JLabel();
		this.jLabelMonth = new javax.swing.JLabel();
		this.jComboBoxMonths = new javax.swing.JComboBox();
		this.jLabelDay = new javax.swing.JLabel();
		this.jComboBoxDays = new javax.swing.JComboBox();
		this.jLabelDegreeLat = new javax.swing.JLabel();
		this.jLabelDegreeLong = new javax.swing.JLabel();
		this.jButtonGenSun = new javax.swing.JButton();
		this.jRadioButtonHorizontal = new javax.swing.JRadioButton();
		this.buttonGroupDiffSundials.add(this.jRadioButtonHorizontal);
		this.jRadioButtonVertical = new javax.swing.JRadioButton();
		this.buttonGroupDiffSundials.add(this.jRadioButtonVertical);
		this.jRadioButtonEqual = new javax.swing.JRadioButton();
		this.buttonGroupDiffSundials.add(this.jRadioButtonEqual);
		this.jButtonSaveCoord = new javax.swing.JButton();
		this.jButtonShowPreSun = new javax.swing.JButton();
		this.jButtonClearVal = new javax.swing.JButton();
		this.jButtonAskGeo = new javax.swing.JButton();

		setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
		setTitle("Sundial App");

		this.jLabelLatitude.setText("Latitude:");

		this.jLabelLongtitude.setText("Longitude:");

		this.jLabelMonth.setText("Month:");

		this.jComboBoxMonths.setMaximumRowCount(12);
		this.jComboBoxMonths.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }));

		this.jLabelDay.setText("Day:");

		this.jComboBoxDays.setMaximumRowCount(12);
		this.jComboBoxDays.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31" }));

		this.jLabelDegreeLat.setText("Degrees");

		this.jLabelDegreeLong.setText("Degrees");

		this.jButtonGenSun.setText("Generate Sundial");
		this.jButtonGenSun.addActionListener(new java.awt.event.ActionListener() {
			@Override
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jButtonGenSunActionPerformed(evt);
			}
		});

		this.jRadioButtonHorizontal.setSelected(true);
		this.jRadioButtonHorizontal.setText("Horizontal");

		this.jRadioButtonEqual.setText("Equitorial");

		this.jButtonSaveCoord.setText("Save Coordinates");
		this.jButtonSaveCoord.setEnabled(false);
		this.jButtonSaveCoord.addActionListener(new java.awt.event.ActionListener() {
			@Override
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jButtonSaveCoordActionPerformed(evt);
			}
		});

		this.jButtonShowPreSun.setText("Show Previous Sundial");
		this.jButtonShowPreSun.setEnabled(false);
		checkFile();
		this.jButtonShowPreSun.addActionListener(new java.awt.event.ActionListener() {
			@Override
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jButtonShowPreSunActionPerformed(evt);
			}
		});

		this.jButtonClearVal.setText("Clear all values");
		this.jButtonClearVal.addActionListener(new java.awt.event.ActionListener() {
			@Override
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jButtonClearValActionPerformed(evt);
			}
		});

		this.jButtonAskGeo.setText("Go askgeo.com for lat&long");
		this.jButtonAskGeo.addActionListener(new java.awt.event.ActionListener() {
			@Override
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jButtonAskGeoActionPerformed(evt);
			}
		});
		
		this.jRadioButtonVertical.setText("Vertical");

		javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
		getContentPane().setLayout(layout);
		layout.setHorizontalGroup(
				layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
				.addGroup(layout.createSequentialGroup()
						.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
								.addGroup(layout.createSequentialGroup()
										.addGap(63, 63, 63)
										.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
												.addGroup(layout.createSequentialGroup()
														.addComponent(this.jLabelMonth)
														.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
														.addComponent(this.jComboBoxMonths, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
														.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
														.addComponent(this.jLabelDay)
														.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
														.addComponent(this.jComboBoxDays, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
														.addGroup(layout.createSequentialGroup()
																.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
																		.addGroup(layout.createSequentialGroup()
																				.addComponent(this.jLabelLongtitude)
																				.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
																				.addComponent(this.jTextFieldLongitude, javax.swing.GroupLayout.PREFERRED_SIZE, 159, javax.swing.GroupLayout.PREFERRED_SIZE))
																				.addGroup(layout.createSequentialGroup()
																						.addComponent(this.jLabelLatitude)
																						.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
																						.addComponent(this.jTextFieldLatitude, javax.swing.GroupLayout.PREFERRED_SIZE, 159, javax.swing.GroupLayout.PREFERRED_SIZE)))
																						.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
																						.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
																								.addComponent(this.jLabelDegreeLat)
																								.addComponent(this.jLabelDegreeLong)))
																								.addGroup(layout.createSequentialGroup()
																										.addComponent(this.jRadioButtonHorizontal)
																										.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
																										.addComponent(this.jRadioButtonVertical)
																										.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
																										.addComponent(this.jRadioButtonEqual)))
																										.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
																										.addComponent(this.jButtonAskGeo))
																										.addGroup(layout.createSequentialGroup()
																												.addContainerGap()
																												.addComponent(this.jButtonClearVal)
																												.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
																												.addComponent(this.jButtonSaveCoord)
																												.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
																												.addComponent(this.jButtonShowPreSun))
																												.addGroup(layout.createSequentialGroup()
																														.addGap(135, 135, 135)
																														.addComponent(this.jButtonGenSun)))
																														.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
				);
		layout.setVerticalGroup(
				layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
				.addGroup(layout.createSequentialGroup()
						.addContainerGap()
						.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
								.addComponent(this.jLabelLatitude)
								.addComponent(this.jTextFieldLatitude, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
								.addComponent(this.jLabelDegreeLat)
								.addComponent(this.jButtonAskGeo))
								.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
								.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
										.addComponent(this.jLabelLongtitude)
										.addComponent(this.jTextFieldLongitude, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
										.addComponent(this.jLabelDegreeLong))
										.addGap(18, 18, 18)
										.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
												.addComponent(this.jLabelMonth)
												.addComponent(this.jComboBoxMonths, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
												.addComponent(this.jLabelDay)
												.addComponent(this.jComboBoxDays, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
												.addGap(18, 18, 18)
												.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
														.addComponent(this.jRadioButtonHorizontal)
														.addComponent(this.jRadioButtonEqual)
														.addComponent(this.jRadioButtonVertical))
														.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 86, Short.MAX_VALUE)
														.addComponent(this.jButtonGenSun)
														.addGap(18, 18, 18)
														.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
																.addComponent(this.jButtonSaveCoord)
																.addComponent(this.jButtonShowPreSun)
																.addComponent(this.jButtonClearVal))
																.addContainerGap())
				);

		pack();
	}// </editor-fold>//GEN-END:initComponents

	/**
	 * @param evt not used
	 */
	private void jButtonGenSunActionPerformed(java.awt.event.ActionEvent evt) {
		testSundial();
	}

	/**
	 * This is used to allow the user to save the current, valid sundial.<br />
	 * Since SundialMath doesn't use equitorial or horizontal, the strings,
	 * horizontal or equitorial need to be passed to SundialSave.<br />
	 * Since SundialMath uses an int to represent the month, need to grab the
	 * current selected item in jComboBoxMonths.
	 * 
	 * @param evt not used
	 */
	private void jButtonSaveCoordActionPerformed(java.awt.event.ActionEvent evt) {
		String month = String.valueOf(this.jComboBoxMonths.getSelectedItem());
		// if horizontal radio button is select, set string to horizontal
		// else equitorial
		String orientation = this.jRadioButtonHorizontal.isSelected() ? "horizontal" : "equitorial";
		
		this.saveCoordinates.saveToFile(this.saveCoordinates.getMathCalculations(), month, orientation);
	}

	/**
	 * Sets the values of the text fields and combo boxes to the last known,
	 * run.
	 * @param evt not used
	 */
	private void jButtonShowPreSunActionPerformed(java.awt.event.ActionEvent evt) {
		String latitude = String.valueOf(this.saveCoordinates.getMathCalculations().getDoubleLatitude());
		String longitude = String.valueOf(this.saveCoordinates.getMathCalculations().getDoubleLongitude());
		this.jComboBoxMonths.setSelectedIndex(this.saveCoordinates.getMathCalculations().getMonth() - 1);
		this.jComboBoxDays.setSelectedIndex(this.saveCoordinates.getMathCalculations().getDay() - 1);
		this.jTextFieldLatitude.setText(latitude);
		this.jTextFieldLongitude.setText(longitude);
	}

	/**
	 * Clears the text fields and sets the combo boxes to the first value.
	 * @param evt not used
	 */
	private void jButtonClearValActionPerformed(java.awt.event.ActionEvent evt) {
		this.jTextFieldLatitude.setText(null);
		this.jTextFieldLongitude.setText(null);
		this.jComboBoxDays.setSelectedIndex(0);
		this.jComboBoxMonths.setSelectedIndex(0);
		this.jRadioButtonHorizontal.setSelected(true);
	}
	
	/**
	 * Should open up a webpage to askgeo.com
	 * 
	 * @param evt not used
	 */
	private void jButtonAskGeoActionPerformed(java.awt.event.ActionEvent evt) {
        openHyperlink(evt);
    }
	
	/**
	 * Tests the sundial the user inputted.<br />
	 * <br />
	 * If the user inputs a string, it's caught in this method.<br />
	 * If the user inputs a very large double, it's caught in TimeZone
	 * constructor.
	 * If the user only fills out one field, it's caught in this method.<br />
	 * If the user selects a bad month/day combination, it's caught by
	 * SundialMath.checkMonthDay<br />
	 * <br />
	 * MonthDay exception is thrown in the TimeZone constructor and the
	 * SundialMath checkMonthDay method in the event of an error.
	 */
	private void testSundial() {
		try {
			SundialMath smath = new SundialMath(Double.parseDouble(this.jTextFieldLatitude.getText()), 
												Double.parseDouble(this.jTextFieldLongitude.getText()),
												Integer.parseInt(this.jComboBoxDays.getSelectedItem().toString()), 
												this.jComboBoxMonths.getSelectedItem().toString());
			
			if(this.jRadioButtonHorizontal.isSelected()){
				HSundialMath hs = new HSundialMath(smath.getLatitude(), smath.getLongitude(), 
													smath.getTimeZoneName(), smath.getHourLines());
			}
			else if(this.jRadioButtonEqual.isSelected()){
				ESundialMath es = new ESundialMath(smath.getLatitude(), smath.getTimeZoneName(), smath.getHourLines());
			}
			else if (this.jRadioButtonVertical.isSelected()) {
				smath = new SundialVertMath(smath);
				VSundialMath vs = new VSundialMath(smath.getLatitude(), smath.getLongitude(), smath.getTimeZoneName(), smath.getHourLines());
			}
			else {
				throw new IllegalArgumentException("Should not be thrown");
			}
			
			this.saveCoordinates.setMathCalculations(smath);
			this.jButtonShowPreSun.setEnabled(true);
			this.jButtonSaveCoord.setEnabled(true);
		} catch (NumberFormatException e) {
			JOptionPane.showMessageDialog(null, "Please enter both latitude and longitude of your location");
			this.jButtonSaveCoord.setEnabled(false);
		} catch (MonthDayException e) {
			JOptionPane.showMessageDialog(null, e.getMessage());
			this.jButtonSaveCoord.setEnabled(false);
		}
	}

	/**
	 * openHyperlink - actionlistner to open a webpage
	 * @param evt not used
	 */
	private void openHyperlink(java.awt.event.ActionEvent evt){
		if(java.awt.Desktop.isDesktopSupported()){
			try{
				java.awt.Desktop.getDesktop().browse(this.uri);
			}
			catch (IOException e){
				System.out.println("Error: action listener hyperterlink");
			}
		}
	}

	/**
	 * Checks to make sure the file contents are legitimate on first run.<br />
	 * 
	 */
	private void checkFile() {
		this.jButtonShowPreSun.setEnabled(this.saveCoordinates.getShowPreviousSundialButton());
	}

	/**
	 * Get URI
	 */
	private void createURI() {
		////////////////////////
		//Link to get lat&long//
		////////////////////////
		//link to get latitude and longitude
		try {
			this.uri = new java.net.URI("http://askgeo.com");
		}
		catch (java.net.URISyntaxException e) {
			// telling the user, "Warning: Network connection not found.
			// Calculations may slightly incorrect"
			JOptionPane.showMessageDialog(null, e);
		}
	}

	/**
	 * @param args the command line arguments
	 */
	public static void main(String args[]) {
		/* Set the Nimbus look and feel */
		//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
		/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
		 * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
		 */
		try {
			for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
				if ("Nimbus".equals(info.getName())) {
					javax.swing.UIManager.setLookAndFeel(info.getClassName());
					break;
				}
			}
		} catch (ClassNotFoundException ex) {
			java.util.logging.Logger.getLogger(SunDialgui.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
		} catch (InstantiationException ex) {
			java.util.logging.Logger.getLogger(SunDialgui.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
		} catch (IllegalAccessException ex) {
			java.util.logging.Logger.getLogger(SunDialgui.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
		} catch (javax.swing.UnsupportedLookAndFeelException ex) {
			java.util.logging.Logger.getLogger(SunDialgui.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
		}
		//</editor-fold>

		/* Create and display the form */
		java.awt.EventQueue.invokeLater(new Runnable() {
			@Override
			public void run() {
				new SunDialgui().setVisible(true);
			}
		});
	}
	// Variables declaration - do not modify//GEN-BEGIN:variables
	private javax.swing.ButtonGroup buttonGroupDiffSundials;
	private javax.swing.JButton jButtonAskGeo;
	private javax.swing.JButton jButtonClearVal;
	private javax.swing.JButton jButtonGenSun;
	private javax.swing.JButton jButtonSaveCoord;
	private javax.swing.JButton jButtonShowPreSun;
	private javax.swing.JComboBox jComboBoxDays;
	private javax.swing.JComboBox jComboBoxMonths;
	private javax.swing.JLabel jLabelDay;
	private javax.swing.JLabel jLabelDegreeLat;
	private javax.swing.JLabel jLabelDegreeLong;
	private javax.swing.JLabel jLabelLatitude;
	private javax.swing.JLabel jLabelLongtitude;
	private javax.swing.JLabel jLabelMonth;
	private javax.swing.JRadioButton jRadioButtonEqual;
	private javax.swing.JRadioButton jRadioButtonHorizontal;
	private javax.swing.JRadioButton jRadioButtonVertical;
	private javax.swing.JTextField jTextFieldLatitude;
	private javax.swing.JTextField jTextFieldLongitude;
	// End of variables declaration//GEN-END:variables
}
